import { DEBUG } from "@/config";
import { Point } from "@/hooks/useConfig";
import useUpdateMaterial from "@/hooks/useUpdateMaterial";
import { useDebug } from "@/stores/debug";
import { useModel } from "@/stores/models";
import { sendMsg } from "@/utils";
import { Gltf, Html, Image, useGLTF, useTexture } from "@react-three/drei";
import { ThreeEvent, useFrame } from "@react-three/fiber";
import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { Box3, DoubleSide, Euler, Group, Mesh, Vector3 } from "three";

/**
 * 可以处理三种点位
 * 1. 只有贴图没有模型 - Image
 * 2. 只有模型没有贴图 - GLTF
 * 3. 既有模型也有贴图 - useGLTF useTexture
 * */
// 记录起始触摸位置
let startX: number;
let startY: number;
export function LoadPoint({
  id,
  name,
  path,
  position = [0, 0, 0],
  rotation = [0, 0, 0],
  scale = 1,
  texture,
  activeDis,
}: Point & { activeDis: number }) {
  const ref = useRef<Group>(null);
  const pos = useModel((state) => state.playerPos);
  const [active, setActive] = useState(false);

  useUpdateMaterial(ref, active);

  useEffect(() => {
    if (!ref.current || !pos) return;
    if (id == 1) {
      !active && setActive(true);
      return;
    }
    let distance = 0;

    if (!path) {
      distance = pos.distanceTo(new Vector3(...position));
    } else {
      // 使用边界框来包裹模型，
      const box = new Box3().setFromObject(ref.current);
      // 计算距离边界框最近的距离
      distance = box.distanceToPoint(pos);
    }

    if (distance < activeDis) {
      setActive(true);
    } else {
      setActive(false);
    }
  }, [pos]);

  useFrame(() => {
    if (!ref.current || id !== 1 || DEBUG) return;
    ref.current.rotation.y += 0.02;
  });

  function onClick(e: ThreeEvent<MouseEvent>) {
    e.stopPropagation();
    if (DEBUG) {
      useDebug.setState({ target: e.eventObject });
    } else {
      // if (!active) return;
      msgToParent();
    }
  }

  function msgToParent() {
    if (id === 1)
      return sendMsg({
        action: "page",
        content: { id, name },
      });
    if (id === 2) {
      return sendMsg({
        action: "link",
        content: { id, name },
      });
    }
    sendMsg({
      action: "pop",
      content: { id, name },
    });
  }

  // 触摸开始事件
  function handlePointerDown(event: ThreeEvent<MouseEvent>) {
    startX = event.clientX;
    startY = event.clientY;
  }

  // 触摸结束事件
  function handlePointerUp(event: ThreeEvent<MouseEvent>) {
    const endX = event.clientX;
    const endY = event.clientY;
    const deltaX = Math.abs(endX - startX);
    const deltaY = Math.abs(endY - startY);

    // 设置一个点击的阈值（例如 10 像素）
    const CLICK_THRESHOLD = 10;

    // 判断是否为“点击”事件
    if (deltaX < CLICK_THRESHOLD && deltaY < CLICK_THRESHOLD) {
      onClick(event);
    }
  }

  function TextureModel() {
    const { scene } = useGLTF(path);
    const map = useTexture(texture!);

    useLayoutEffect(() => {
      map.flipY = false;
      scene.traverse((obj) => {
        if (obj instanceof Mesh) {
          obj.material.map = map;
        }
      });
    }, [scene, map]);

    return (
      <group
        name={name}
        position={new Vector3(...position)}
        rotation={new Euler(...rotation)}
        scale={scale}
        userData={{ position, rotation, scale }}
        onPointerDown={handlePointerDown}
        onPointerUp={handlePointerUp}
      >
        <primitive object={scene} />
      </group>
    );
  }

  return (
    <group ref={ref}>
      {!path ? (
        <Image
          url={texture!}
          name={name}
          position={new Vector3(...position)}
          rotation={new Euler(...rotation)}
          scale={scale as number | [number, number]}
          onPointerDown={handlePointerDown}
          onPointerUp={handlePointerUp}
          userData={{ position, rotation, scale }}
          side={DoubleSide}
        />
      ) : texture ? (
        <TextureModel />
      ) : (
        <Gltf
          name={name}
          src={path}
          position={new Vector3(...position)}
          rotation={new Euler(...rotation)}
          scale={scale}
          onPointerDown={handlePointerDown}
          onPointerUp={handlePointerUp}
          userData={{ position, rotation, scale }}
        >
          <Html position={[0, 0, 0]} center>
            <img
              src={"./shiny.png"}
              alt=""
              className="card"
              onClick={msgToParent}
            />
          </Html>
        </Gltf>
      )}
    </group>
  );
}
